package com.ds.app.proxy;

import com.ds.app.ModuleNotFoundException;
import com.ds.app.database.DBBaseManager;
import com.ds.app.inner.EIModule;
import com.ds.common.CommonConfig;
import com.ds.common.logging.Log;
import com.ds.common.logging.LogFactory;
import com.ds.org.conf.OrgConfig;
import com.ds.org.conf.OrgConstants;
import com.ds.org.conf.Query;
import com.ds.org.conf.Query.ColumnMapping;
import com.ds.org.conf.Query.SqlClause;
import com.ds.server.eumus.ConfigCode;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

public class ModuleProxyManager extends DBBaseManager {

    protected static Log log = LogFactory.getLog(OrgConstants.CONFIG_KEY.getType(), ModuleProxyManager.class);

    private ConfigCode subSystemId;

    static ModuleProxyManager manager;

    public static ModuleProxyManager getInstance(ConfigCode subSystemId) {
        if (manager == null) {
            manager = new ModuleProxyManager(subSystemId);
        }
        return manager;
    }

    ModuleProxyManager(ConfigCode subSystemId) {
        super(subSystemId);
        String enabled = CommonConfig.getValue(OrgConstants.CONFIG_KEY.getType() + ".cache.enabled");
        this.cacheEnabled = Boolean.valueOf(enabled).booleanValue();
        this.subSystemId = subSystemId;

        this.config = OrgConfig.getInstance();
    }

    public ModuleProxy loadModuleByKey(EIModule module) throws ModuleNotFoundException {
        return loadFromDb(module);
    }

    private OrgConfig getConfig() {
        OrgConfig config = OrgConfig.getInstance(this.subSystemId);
        return config;
    }

    synchronized ModuleProxy loadFromDb(EIModule module) throws ModuleNotFoundException {
        ModuleProxy moduleProxy = new ModuleProxy(module, this.subSystemId);
        loadApps(moduleProxy);
        // this.loadPersons(moduleProxy);
        // this.loadDisablePersons(moduleProxy);
        // if (getConfig().isSupportPersonDuty()) {
        // loadDuties(moduleProxy);
        // }
        //
        // if (getConfig().isSupportPersonGroup()) {
        // loadGroups(moduleProxy);
        // }
        //
        // if (getConfig().isSupportPersonPosition()) {
        // loadPositions(moduleProxy);
        // }
        //
        // if (getConfig().isSupportPersonRole()) {
        // loadRoles(moduleProxy);
        // }

        return moduleProxy;

    }

    synchronized void loadApps(ModuleProxy proxy) {
        ResultSet rs = null;
        Query query = null;
        SqlClause sqlClause = null;
        Map columnMap = null;
        String strSql = null;

        // 2.应用信息
        query = config.getQuery("Module-App");
        if (query != null) {
            sqlClause = query.getSqlClause("basic");
            if (sqlClause != null) {
                PreparedStatement ps = null;
                Connection c = null;
                columnMap = sqlClause.getColumnMappings();
                strSql = buildSql(sqlClause, proxy.getID());
                try {
                    proxy.setAppIdList_is_initialized(true);
                    proxy.setAppIdList(null);
                    c = this.getConnection();
                    ps = c.prepareStatement(strSql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

                    if (ps.execute()) {

                        rs = ps.executeQuery();
                        while (rs.next()) {
                            proxy.addApp(getString(rs, columnMap.get("appId")));
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    getManager().close(ps, rs);
                    freeConnection(c);
                }
            }
        }

    }

    /**
     * 对人员新增授权
     */
    synchronized void loadPersons(ModuleProxy proxy) {

        ResultSet rs = null;
        Query query = null;
        SqlClause sqlClause = null;
        Map columnMap = null;
        String strSql = null;

        query = getConfig().getQuery("Module-Person");
        if (query != null) {
            sqlClause = query.getSqlClause("basic");
            if (sqlClause != null) {
                PreparedStatement ps = null;
                Connection c = null;
                columnMap = sqlClause.getColumnMappings();
                strSql = buildSql(sqlClause, proxy.getID());
                try {
                    proxy.setPersonIdList_is_initialized(true);
                    proxy.setPersonIdList(null);
                    c = this.getConnection();
                    ps = c.prepareStatement(strSql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

                    if (ps.execute()) {

                        rs = ps.executeQuery();
                        while (rs.next()) {
                            proxy.addPerson(getString(rs, columnMap.get("personId")));
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    getManager().close(ps, rs);
                    freeConnection(c);
                }
            }
        }
    }

    /**
     * 对组织机构授权
     */
    synchronized void loadOrgs(ModuleProxy proxy) {

        ResultSet rs = null;
        Query query = null;
        SqlClause sqlClause = null;
        Map columnMap = null;
        String strSql = null;

        query = getConfig().getQuery("Module-Org");
        if (query != null) {
            sqlClause = query.getSqlClause("basic");
            if (sqlClause != null) {
                PreparedStatement ps = null;
                Connection c = null;
                columnMap = sqlClause.getColumnMappings();
                strSql = buildSql(sqlClause, proxy.getID());
                try {
                    proxy.setOrgIdList_is_initialized(true);
                    proxy.setOrgIdList(null);
                    c = this.getConnection();
                    ps = c.prepareStatement(strSql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

                    if (ps.execute()) {
                        rs = ps.executeQuery();
                        while (rs.next()) {
                            proxy.addOrg(getString(rs, columnMap.get("orgId")));
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    getManager().close(ps, rs);
                    freeConnection(c);
                }
            }
        }
    }

    /**
     * 对权限点禁用
     */
    synchronized void loadDisablePersons(ModuleProxy proxy) {

        ResultSet rs = null;
        Query query = null;
        SqlClause sqlClause = null;
        Map columnMap = null;
        String strSql = null;

        // 3.人员授权信息
        query = getConfig().getQuery("Module-DisablePerson");
        if (query != null) {
            sqlClause = query.getSqlClause("basic");
            if (sqlClause != null) {
                PreparedStatement ps = null;
                Connection c = null;
                columnMap = sqlClause.getColumnMappings();
                strSql = buildSql(sqlClause, proxy.getID());
                try {
                    proxy.setDisablePersonIdList(null);
                    proxy.setDisablePersonIdList_is_initialized(true);
                    c = this.getConnection();
                    ps = c.prepareStatement(strSql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                    if (ps.execute()) {
                        rs = ps.executeQuery();
                        while (rs.next()) {
                            proxy.addDisablePerson(getString(rs, columnMap.get("personId")));
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    getManager().close(ps, rs);
                    freeConnection(c);
                }
            }
        }
    }

    synchronized void loadRoles(ModuleProxy proxy) {

        ResultSet rs = null;
        Query query = null;
        SqlClause sqlClause = null;
        Map columnMap = null;
        String strSql = null;

        query = getConfig().getQuery("Module-PersonRole");
        if (query != null) {
            sqlClause = query.getSqlClause("basic");
            if (sqlClause != null) {
                PreparedStatement ps = null;
                Connection c = null;
                columnMap = sqlClause.getColumnMappings();
                strSql = buildSql(sqlClause, proxy.getID());
                try {
                    proxy.setRoleIdList(null);
                    proxy.setRoleIdList_is_initialized(true);
                    c = this.getConnection();
                    ps = c.prepareStatement(strSql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                    if (ps.execute()) {
                        rs = ps.executeQuery();
                        while (rs.next()) {
                            proxy.addRole(getString(rs, columnMap.get("personRoleId")));
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    getManager().close(ps, rs);
                    freeConnection(c);
                }
            }
        }
    }

    private String buildSql(SqlClause sqlClause, String ID) {
        Map columnMap = sqlClause.getColumnMappings();
        String strSql = sqlClause.getMainClause();
        String strWhere = sqlClause.getWhereClause();
        String orderClause = sqlClause.getOrderClause();
        if (strWhere != null && !strWhere.equals("")) {

            strSql = strSql + " " + strWhere + " AND " + ((ColumnMapping) columnMap.get("moduleId")).getColumn() + "='" + ID + "'";

        } else {
            strSql = strSql + " WHERE " + ((ColumnMapping) columnMap.get("moduleId")).getColumn() + "='" + ID + "'";
        }
        if (orderClause != null) {
            strSql = strSql + " " + orderClause;
        }

        return strSql;
    }

    void insertDisablePersonModule(String moduleId, String personId) {
        Query query = getConfig().getQuery("Module-DisablePerson");
        SqlClause sqlClause = query.getSqlClause("basic");
        Map columnMap = sqlClause.getColumnMappings();
        StringBuffer _sql = new StringBuffer(sqlClause.getInsertClause() + "(");
        int _dirtyCount = 0;
        _sql.append(columnMap.get("uuid")).append(",");
        _dirtyCount++;
        _sql.append(columnMap.get("moduleId")).append(",");
        _dirtyCount++;
        _sql.append(columnMap.get("personId")).append(",");
        _dirtyCount++;
        _sql.setLength(_sql.length() - 1);
        _sql.append(") values (");
        for (int i = 0; i < _dirtyCount; i++)
            _sql.append("?,");
        _sql.setLength(_sql.length() - 1);
        _sql.append(")");
        PreparedStatement ps = null;
        Connection c = null;

        try {
            c = this.getConnection();
            ps = c.prepareStatement(_sql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            _dirtyCount = 0;
            ps.setString(++_dirtyCount, generationUUID());
            ps.setString(++_dirtyCount, moduleId);
            ps.setString(++_dirtyCount, personId);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            getManager().close(ps);
            freeConnection(c);
        }

    }

    private void deleteDisablePersonModule(String moduleId, String personId) {
        Query query = getConfig().getQuery("Module-DisablePerson");
        SqlClause sqlClause = query.getSqlClause("basic");
        Map columnMap = sqlClause.getColumnMappings();
        String _sql = sqlClause.getDeleteClause() + " WHERE " + ((ColumnMapping) columnMap.get("personId")).getColumn() + " = ? AND " + ((ColumnMapping) columnMap.get("moduleId")).getColumn() + " = ?";
        PreparedStatement ps = null;
        Connection c = null;
        try {
            c = this.getConnection();
            ps = c.prepareStatement(_sql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            ps.setString(1, personId);
            ps.setString(2, moduleId);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            getManager().close(ps);
            freeConnection(c);
        }

    }

    void insertPersonModule(String moduleId, String personId) {
        Query query = getConfig().getQuery("Module-Person");
        SqlClause sqlClause = query.getSqlClause("basic");
        Map columnMap = sqlClause.getColumnMappings();
        StringBuffer _sql = new StringBuffer(sqlClause.getInsertClause() + "(");
        int _dirtyCount = 0;
        _sql.append(columnMap.get("uuid")).append(",");
        _dirtyCount++;
        _sql.append(columnMap.get("moduleId")).append(",");
        _dirtyCount++;
        _sql.append(columnMap.get("personId")).append(",");
        _dirtyCount++;
        _sql.setLength(_sql.length() - 1);
        _sql.append(") values (");
        for (int i = 0; i < _dirtyCount; i++)
            _sql.append("?,");
        _sql.setLength(_sql.length() - 1);
        _sql.append(")");
        PreparedStatement ps = null;
        Connection c = null;

        try {
            c = this.getConnection();
            ps = c.prepareStatement(_sql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            _dirtyCount = 0;
            ps.setString(++_dirtyCount, generationUUID());
            ps.setString(++_dirtyCount, moduleId);
            ps.setString(++_dirtyCount, personId);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            getManager().close(ps);
            freeConnection(c);
        }

    }

    private void deletePersonModule(String moduleId, String personId) {
        Query query = getConfig().getQuery("Module-Person");
        SqlClause sqlClause = query.getSqlClause("basic");
        Map columnMap = sqlClause.getColumnMappings();
        String _sql = sqlClause.getDeleteClause() + " WHERE " + ((ColumnMapping) columnMap.get("personId")).getColumn() + " = ? AND " + ((ColumnMapping) columnMap.get("moduleId")).getColumn() + " = ?";
        PreparedStatement ps = null;
        Connection c = null;
        try {
            c = this.getConnection();
            ps = c.prepareStatement(_sql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            ps.setString(1, personId);
            ps.setString(2, moduleId);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            getManager().close(ps);
            freeConnection(c);
        }

    }

}
